package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Region;
import cn.wolfcode.luowowo.query.DestinationQuery;
import cn.wolfcode.luowowo.repository.DestinationRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IRegionService;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class DestinationServiceImpl implements IDestinationService {
    @Autowired
    private DestinationRepository repository;

    @Autowired
    private IRegionService regionService;

    @Autowired
    private MongoTemplate template;

    @Override
    public List<Destination> list() {
        //查所有
        List<Destination> list = repository.findAll();
        return list;
    }

    @Override
    public List<Destination> getByDeep(int deep) {
        List<Destination> list = repository.findByDeep(deep);
        return list;
    }

    @Override
    public List<Destination> getDestByRegionId(String rid) {
        //ids是region的id，我们要查出region，在通过region.getrefId()才能拿到区域关联的目的地的id
        Region region = regionService.get(rid);
        //一个区域挂载多个目的地
        List<String> refIds = region.getRefIds();
        //通过refIds查询目的地: in 语法
        return repository.findByIdIn(refIds);
    }

    //分页
    @Override
    public Page<Destination> query(DestinationQuery qo) {
        Query query = new Query();

        //面包屑，导航查询
        if (StringUtils.hasLength(qo.getParentId())) {
            query.addCriteria(Criteria.where("parentId").is(qo.getParentId()));
        } else {
            //没有值就查根的数据
            query.addCriteria(Criteria.where("parentId").is(null));
        }

        //高级查询的条件
        if (StringUtils.hasLength(qo.getKeyword())) {
            query.addCriteria(Criteria.where("name").regex(".*" + qo.getKeyword() + ".*"));
        }

        //PageRequest pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
        //return DBHelper.query(template, Destination.class, query, pageable);
        return DBHelper.query(template, Destination.class, query, qo.getPageable());
    }

    //查询吐司
    @Override
    public List<Destination> getToasts(String parentId) {
        if (!StringUtils.hasLength(parentId)) {
            return Collections.emptyList();//返回空的list集合
        }

        ArrayList<Destination> list = new ArrayList<>();

        //查询当前目的地：方式1：递归的方式查询
        //createToast(list, parentId);
        //方式2：while循环查询
        while (true) {
            //结束条件:parentId为null是表示目的地已经为根
            if (parentId == null) {
                break;
            } else {
                Optional<Destination> optional = repository.findById(parentId);
                list.add(optional.get());
                //将刚刚查到的父级目的地的parentId覆盖原来的parentId，这样才可能满足结束条件
                parentId = optional.get().getParentId();
            }
        }

        Collections.reverse(list);//反转list集合
        return list;
    }

    //创建toast
    //跟>>中国>>广东>>广州>>天河区
    private void createToast(ArrayList<Destination> list, String parentId) {
        Optional<Destination> optional = repository.findById(parentId);//通过当前目的地带过来的parentId查到的就是上一级的目的地名
        //如果parentId差不到值就表示为根
        if (!optional.isPresent()) {
            return;
        }
        list.add(optional.get());
        //如果还有上一级，就调用自己继续查
        if (StringUtils.hasLength(optional.get().getParentId())) {
            createToast(list, optional.get().getParentId());
        }
    }

    @Override
    public Destination getDeepNmaeById(String destId) {
        return template.findById(destId, Destination.class);
    }

    //编辑目的地的简介信息
    @Override
    public void updateInfo(String id, String info) {
        //更新
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("info", info);
        template.upsert(query, update, Destination.class);
    }

    //查询指定区域下挂载的目的地
    @Override
    public List<Destination> getDestByRegionIdForApi(String regionId) {
        //第一层：查询区域下挂载的子目的地
        List<Destination> list = null;
        if ("-1".equals(regionId)){
            //国内的regionId为-1
            list = repository.findByParentName("中国");
        }else {
            //查询挂载的目的地的id集合
            Region region = regionService.get(regionId);
            List<String> refIds = region.getRefIds();
            //查询关联的目的地集合中的所有目的地
            list = repository.findByIdIn(refIds);
        }
        //第二层：查询关联目的地下的字目的地
        //直接关联查询
        for (Destination destination : list) {
            //目的地下的子目的地太多，用JPA的方式让他只显示一部分
            PageRequest of = PageRequest.of(0, 5);
            //以父目的地的name做为条件查询子目的地
            List<Destination> children = repository.findByParentId(destination.getId(),of);
            destination.setChildren(children);
        }
        return list;
    }

    //通过destId查询目的地
    @Override
    public Destination get(String destId) {
        Optional<Destination> optional = repository.findById(destId);
        return optional.get();
    }

    @Override
    public Destination getByName(String keyword) {
        return repository.findByName(keyword);
    }
}
